{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ed987a2f-5811-43f4-9a7b-1dd3f1278f0f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# File: friction.ipynb\n",
    "# Code: Claude Code and Codex\n",
    "# Review: Ryoichi Ando (ryoichi.ando@zozo.com)\n",
    "# License: Apache v2.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1845cfba-4cda-4917-905c-2991ada078b1",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from frontend import App\n",
    "\n",
    "# create an app\n",
    "app = App.create(\"friction\")\n",
    "\n",
    "# create an armadillo tetrahedral mesh\n",
    "V, F, T = app.mesh.preset(\"armadillo\").decimate(2400).tetrahedralize().normalize()\n",
    "app.asset.add.tet(\"armadillo\", V, F, T)\n",
    "\n",
    "# create a rectangular slope mesh\n",
    "V, F = app.mesh.rectangle(res_x=43, width=10, height=3, ex=[1, 0, 0], ey=[0, 0, 1])\n",
    "app.asset.add.tri(\"slope\", V, F)\n",
    "\n",
    "# create a scene\n",
    "scene = app.scene.create()\n",
    "\n",
    "# add armadillo with friction properties\n",
    "armadillo = scene.add(\"armadillo\")\n",
    "armadillo.param.set(\"poiss-rat\", 0.49).set(\"friction\", 0.51)\n",
    "armadillo.rotate(180, \"y\").rotate(-90, \"x\").rotate(-30, \"z\").at(\n",
    "    -3.8, 2.35, -0.25\n",
    ").jitter()\n",
    "\n",
    "# add sloped surface with angle based on friction coefficient\n",
    "deg = 180 * np.arctan(0.5) / np.pi\n",
    "scene.add(\"slope\").rotate(-deg, \"z\").pin()\n",
    "\n",
    "# compile the scene and report stats\n",
    "scene = scene.build().report()\n",
    "\n",
    "# preview the initial scene\n",
    "scene.preview()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ab059354-7c0d-4fd9-a5fe-544af3c3d79f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# create a new session with the compiled scene\n",
    "session = app.session.create(scene)\n",
    "\n",
    "# set session parameters\n",
    "(\n",
    "    session.param.set(\"dt\", 0.01)\n",
    "    .set(\"min-newton-steps\", 32)\n",
    "    .set(\"frames\", 700)\n",
    ")\n",
    "\n",
    "# build this session\n",
    "session = session.build()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6f2c2ed4-5839-4c6a-947b-9e772431fc95",
   "metadata": {},
   "outputs": [],
   "source": [
    "# start the simulation and live-preview the results\n",
    "session.start().preview()\n",
    "\n",
    "# also show simulation logs in realtime\n",
    "session.stream()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d70cac9b-43b9-4355-9426-6953dea667dd",
   "metadata": {},
   "outputs": [],
   "source": [
    "# create an animation from the simulation results\n",
    "session.animate()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b6528c86-0218-4ea9-98ec-033ba1a28f17",
   "metadata": {},
   "outputs": [],
   "source": [
    "# export the animation to file\n",
    "session.export.animation()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c1401b65-dfbb-4739-ad0d-81bdbb25097c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# this is for CI\n",
    "if app.ci:\n",
    "    assert session.finished()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
